﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using ATTools.Models;
using ATTools.Services;
using ATTools.ViewModels;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Core.Contents.Controllers;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.UI.Admin;

namespace ATTools.Controllers
{
    [Admin, OrchardFeature("ATTools.VoiceCommands")] //Need the Admin attribute. If omitted it wont show up with the admin panels around the VoiceList.
    public class VoiceAdminController : Controller, IUpdateModel
    {
        private const string NotAuthorizedToManageVoiceCommands = "Not authorized to manage Voice Commands";

        private readonly IVoiceCommandService _voiceCommandService;

        public IOrchardServices Services { get; set; }
        public Localizer T { get; set; }

        public VoiceAdminController(IOrchardServices services, IVoiceCommandService voiceCommandService)
        {
            Services = services;
            _voiceCommandService = voiceCommandService;

            T = NullLocalizer.Instance;
        }


        public ActionResult VoiceList()
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            IEnumerable<VoiceCommandRecord> commands = _voiceCommandService.GetVoiceCommands();
            var entries = commands.Select(CreateVoiceCommandEntry).ToList();
            var model = new VoiceCommandsAdminIndexViewModel { VoiceCommands = entries };
            return View(model);

        }


        public ActionResult NewVoiceCommand()
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            var model =  new VoiceCommandsAdminCreateViewModel();
            return View(model);

        }

        [HttpPost, ActionName("NewVoiceCommand")]
        [FormValueRequired("submit.Create")]
        public ActionResult NewVoiceCommandPOST()
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            var viewModel = new VoiceCommandsAdminCreateViewModel();

            if (!TryUpdateModel(viewModel))
            {
                ViewData["CreateVoiceCommand"] = viewModel;
                return VoiceList();
            }

            _voiceCommandService.CreateVoiceCommand(viewModel.Description, viewModel.CommandType, viewModel.CommandData);

            return RedirectToAction("VoiceList");
        }

        private static VoiceCommandEntry CreateVoiceCommandEntry(VoiceCommandRecord voiceCommandRecord)
        {
            return new VoiceCommandEntry
            {
                VoiceCommand = voiceCommandRecord,
                IsChecked = false,
            };
        }

        [HttpPost]
        [FormValueRequired("submit.BulkEdit")]
        public ActionResult VoiceList(FormCollection input)
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            var viewModel = new VoiceCommandsAdminIndexViewModel { VoiceCommands = new List<VoiceCommandEntry>(), BulkAction = new VoiceCommandAdminIndexBulkAction() };

            if (!TryUpdateModel(viewModel))
            {
                return View(viewModel);
            }

            IEnumerable<VoiceCommandEntry> checkedEntries = viewModel.VoiceCommands.Where(t => t.IsChecked);
            switch (viewModel.BulkAction)
            {
                case VoiceCommandAdminIndexBulkAction.None:
                    break;
                case VoiceCommandAdminIndexBulkAction.Delete:
                    foreach (VoiceCommandEntry entry in checkedEntries)
                    {
                        _voiceCommandService.DeleteVoiceCommand(entry.VoiceCommand.Id);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }

            return RedirectToAction("VoiceList");
        }

        public ActionResult EditVoiceCommand(int id)
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            var record = _voiceCommandService.GetVoiceCommand(id);

            var model = new VoiceCommandsAdminEditViewModel { Id = record.Id, Description = record.Description, CommandType = (CommandType) record.CommandType, CommandData = record.CommandData };
            return View(model);

        }

        [HttpPost]
        public ActionResult EditVoiceCommand(FormCollection input)
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            var viewModel = new VoiceCommandsAdminEditViewModel();

            if (!TryUpdateModel(viewModel))
            {
                return View(viewModel);
            }

            _voiceCommandService.UpdateVoiceCommand(viewModel.Id, viewModel.Description, viewModel.CommandType, viewModel.CommandData);
            return RedirectToAction("VoiceList");
        }

        [HttpPost]
        public ActionResult RemoveVoiceCommand(int id)
        {
            if (!Services.Authorizer.Authorize(Permissions.ManageVoiceCommands, T(NotAuthorizedToManageVoiceCommands)))
                return new HttpUnauthorizedResult();

            VoiceCommandRecord voiceCommandRecord = _voiceCommandService.GetVoiceCommand(id);

            if (voiceCommandRecord == null)
                return new HttpNotFoundResult();

            _voiceCommandService.DeleteVoiceCommand(id);

            return RedirectToAction("VoiceList");
        }

        #region IUpdateModel Members

        public void AddModelError(string key, Orchard.Localization.LocalizedString errorMessage)
        {
            ModelState.AddModelError(key, errorMessage.ToString());
        }

        public new bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class
        {
            return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
        }

        #endregion

    }

}